package cn.com.cetccst.vpn;

import static cn.com.cetccst.vpn.VPNConstants.VPN_STATUS.VPN_STATUS_CONFIG_READY;
import static cn.com.cetccst.vpn.VPNConstants.VPN_STATUS.VPN_STATUS_CONNECTED;
import static cn.com.cetccst.vpn.VPNConstants.VPN_STATUS.VPN_STATUS_LOGIN_FAILED;
import static cn.com.cetccst.vpn.VPNConstants.VPN_STATUS.VPN_STATUS_LOGOUT;
import static cn.com.cetccst.vpn.VPNConstants.VPN_STATUS.VPN_STATUS_LOGOUT_FAILED;
import static cn.com.cetccst.vpn.VPNConstants.VPN_STATUS.VPN_STATUS_UPDATE_CONFIG;

import android.content.Context;
import android.content.Intent;

import java.util.ArrayList;
import java.util.List;

import cn.com.cetccst.vpn.callback.ICommonCallback;
import cn.com.cetccst.vpn.callback.IGetAdServerCallback;
import cn.com.cetccst.vpn.callback.ILoginCallback;
import cn.com.cetccst.vpn.callback.IServerStatusCallback;
import cn.com.cetccst.vpn.callback.IVpnEventCallback;
import cn.com.cetccst.vpn.verdor.IVpn;
import cn.com.cetccst.vpn.verdor.NoVendor;
import cn.com.cetccst.vpn.verdor.secportal.SecPortalVpn;

public class SSVPNManager {

    private static final String TAG = "VPNManager";
    private Context mContext;
    private IVpn mVpn;
    private static SSVPNManager INSTANCE;
    private ArrayList<String> mAdServers = new ArrayList<>();

    public SSVPNManager(Context context) {
        mContext = context;

        //todo 获取下发的VPN配置信息切换厂商
        setVPNVendor("westone");
    }

    public void setVPNVendor(String vpnVendor) {
        if (!isVPNFeatureEnable()) {
            log("vpn feature is disabled, no need set vpn vendor");
            return;
        }
        //todo 根据不同名称使用不同的vpn厂商
        if (VPNConstants.VPN_VENDOR.WESTONE.equalsIgnoreCase(vpnVendor)) {
            mVpn = new SecPortalVpn(mContext);
        } else {
            mVpn = new NoVendor();
        }
        mVpn.init(mContext);
        mVpn.setLoginCallback(mLogInOutCallback);
        mVpn.setVpnEventCallback(mVpnEventCallback);
        mVpn.setServerStatusCallback(mVpnServerStatusCallback);
    }

    public static SSVPNManager getInstance() {
        return INSTANCE;
    }

    public static void initialize(Context context) {
        INSTANCE = new SSVPNManager(context);
    }

    public IVpnEventCallback mVpnEventCallback = new IVpnEventCallback() {
        @Override
        public void onVpnEvent(int event) {
            //todo
            log("onVpnEvent  :" + event);
        }
    };

    public IServerStatusCallback mVpnServerStatusCallback = new IServerStatusCallback() {
        @Override
        public void onServerStatus(int status) {
            log("onServerStatus  :" + status);
            if (status == VPNConstants.VPN_STATUS.VPN_STATUS_CONNECTING) {
                onVPNStatusChanged(status, status, "");
            }
        }
    };
    public ILoginCallback mLogInOutCallback = new ILoginCallback() {
        @Override
        public void onLoginSuccess() {
            log("get vpn login success callback.");
            onVPNStatusChanged(VPN_STATUS_CONNECTED, VPN_STATUS_CONNECTED, "");
        }

        @Override
        public void onLoginFailed(int errorCode, String errMsg) {
            log("onLoginFailed error: " + errMsg + ", errorCode:" + errorCode);
            if (errorCode == ErrorType.ERROR_REPEAT_LOGIN) {
                onVPNStatusChanged(getVpnState(), errorCode, errMsg);
                return;
            }
            onVPNStatusChanged(VPN_STATUS_LOGIN_FAILED, errorCode, errMsg);
            log("onLoginFailed, set vpn status disconnected.");
        }

        @Override
        public void trustCert(String user, String issue, String valideDate) {

        }

        @Override
        public void requestVpn(Intent intent, int requestCode) {
            log("wsgTunnelRequestVpn startActivityForResult: " + intent + ", requestCode: " + requestCode);
            onVPNChannelRequest(intent, requestCode);
        }

        @Override
        public void onLogoutSuccess() {
            onVPNStatusChanged(VPN_STATUS_LOGOUT, VPN_STATUS_LOGOUT, "");
            log("VPN logout successfully");
        }

        @Override
        public void onLogoutFailed(int errorCode, String errMsg) {
            log("onLogoutFailed error: " + errMsg + ", errorCode:" + errorCode);
            onVPNStatusChanged(VPN_STATUS_LOGOUT_FAILED, errorCode, errMsg);
        }
    };

    //todo 使用配置文件
    public boolean isVPNFeatureEnable() {
        return true;
    }

    public int getVpnState() {
        return mVpn.getEventStatus();
    }

    //todo 使用配置文件获取当前认证类型
    public int getAuthType() {
        return VPNConstants.AUTH_TYPE.AUTH_TYPE_USER;
    }

    //todo 具体实现
    protected void onVPNChannelRequest(Intent originalIntent, int requestCode) {
    }

    protected void onVPNStatusChanged(int vpnChannelStatus, int errorCode, String errorMsg) {
    }

    public void configVpnInternetWhiteList(String packageName) {
        mVpn.setInternetWhiteApp(packageName);
    }

    public void updateServerInfo(String addr, int port, String alias) {
        mVpn.updateServerInfo(addr, port, alias);
    }

    public void loginByCert() {
        mVpn.loginByCert("11111111");
    }

    public void loginByUser(String userName, String pwd) {
        mVpn.loginByUserName(userName, pwd);
    }

    public void loginByAd(String server, String userName, String pwd) {
        mVpn.loginByAd(server, userName, pwd);
    }

    public void prepareVpn(Context context) {
        mVpn.prepare();
    }

    public void logout() {
        log("logout");
        mVpn.logout();
    }

    public void setPinCode(String code) {
        mVpn.setPinCode(code);
    }

    public void changePinPwd(String oldPinCode, String newPinCode, final ICommonCallback vpnChangePwdListener) {
        mVpn.changePinPwd(oldPinCode, newPinCode, vpnChangePwdListener);
    }

    public void changeUserPwd(String userName, String oldPwd, String newPwd, final ICommonCallback vpnChangePwdListener) {
        mVpn.changeUserPwd(userName, oldPwd, newPwd, vpnChangePwdListener);
    }

    //AD域现在可能已经不用了，先保留，后期有具体设计再删除
    public ArrayList<String> getAdServers() {
        return mAdServers;
    }

    public void setAdServers(List<String> adServers) {
        mAdServers.clear();
        mAdServers.addAll(adServers);
    }

    public void requestAdServerList(IGetAdServerCallback vpnGetADListener) {
        mVpn.getAdServer(vpnGetADListener);
    }

    public void configVpnWhiteList(ArrayList<String> vpnWhiteListPkgName) {
        mVpn.setWhiteAppList(vpnWhiteListPkgName);
        log("Config VPN vpn white list: " + mVpn.getWhiteAppList());
    }

    private void log(String msg) {
        log(msg, null);
    }

    private void log(String msg, Throwable throwable) {
//        Logger.log(Log.INFO, TAG, msg, throwable);
    }
}
